﻿using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;

using SManaModel.models;

using System.Text;

namespace SManaApi.Extensions
{
    /// <summary>
    /// API身份验证
    /// </summary>
    public static class AuthenticationExtension
    {
        private static readonly TokenConfig DefaultConfig = new TokenConfig()
        {
            Issuer = "metest.com",
            AccessExpiration = 60,
            RefreshExpiration = 60,
            Secret = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDI2a2EJ7m872v0afyoSDJT2o1+SitIeJSWtLJU8/Wz2m7gStexajkeD+Lka6DSTy8gt9UwfgVQo6uKjVLG5Ex7PiGOODVqAEghBuS7JzIYU5RvI543nNDAPfnJsas96mSA7L/mD7RTE2drj6hf3oZjJpMPZUQI/B1Qjb5H3K3PNwIDAQAB",
            Audience = "webapi"
        };

        /// <summary>
        /// 配置 Authentication service
        /// </summary>
        /// <param name="services"></param>
        /// <param name="tokenConfig"></param>
        public static void AddAuthenticationService(this IServiceCollection services, TokenConfig? tokenConfig = null)
        {
            tokenConfig ??= DefaultConfig;
            services.AddSingleton<TokenConfig>(tokenConfig);
            //services.AddAuthentication(configureOptions =>
            //{
            //    configureOptions.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
            //    configureOptions.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
            //})
            services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
            .AddJwtBearer(jwtBearerOptions =>
                {
                    jwtBearerOptions.RequireHttpsMetadata = false;
                    jwtBearerOptions.SaveToken = true;
                    jwtBearerOptions.TokenValidationParameters = new TokenValidationParameters
                    {
                        ValidateIssuerSigningKey = true, //是否验证SecurityKey
                        IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(tokenConfig.Secret)),
                        ValidateIssuer = true, //是否验证Issuer
                        ValidateAudience = true, //是否验证Audience
                        ValidateLifetime = true, //是否验证失效时间
                        ValidAudience = tokenConfig.Audience, //Audience
                        ValidIssuer = tokenConfig.Issuer, //Issuer，这两项和前面签发jwt的设置一致
                        ClockSkew = TimeSpan.FromSeconds(30), //Token过期时间偏差
                    };
                    jwtBearerOptions.Events = new JwtBearerEvents
                    {
                        OnAuthenticationFailed = context =>
                        {
                            //Token expired
                            if (context.Exception.GetType() == typeof(SecurityTokenExpiredException))
                            {
                                context.Response.Headers.Add("Token-Expired", "true");
                            }
                            return Task.CompletedTask;
                        }
                    };
                });

        }
    }
}
